#nullable enable

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PHMEE.CommonUtils;
using PHMEE.TDengineInfrastructure;

namespace PHMEE.EnergyEfficiency;

public sealed class ShaftPowerMeterTdRepository : BaseTdRepository, IShaftPowerMeterTdRepository
{
    /// <summary>
    /// 轴功率计 位于能效库
    /// </summary>
    private const DbPrefixEnum DbPrefix = DbPrefixEnum.Ee;

    /// <summary>
    /// 轴功率计 约定好的超级表名
    /// </summary>
    private const string SuperTableName = "shaft_power_meter";

    /// <summary>
    /// 轴功率计 约定好的子表名
    /// </summary>
    private const string SubTableName = "spm_001";

    private readonly ILogger<ShaftPowerMeterTdRepository> _logger;

    public ShaftPowerMeterTdRepository(IOptionsSnapshot<TDengineOptions> tdengineOptions,
        ILogger<ShaftPowerMeterTdRepository> logger) : base(tdengineOptions)
    {
        _logger = logger;
    }

    // /// <summary>
    // /// 查询 shaft_power_meter 指定时间范围内的最新一条数据，前闭后闭区间
    // /// </summary>
    // /// <param name="vesselId"></param>
    // /// <param name="startDateTime"></param>
    // /// <param name="endDateTime"></param>
    // /// <returns></returns>
    // public async Task<ShaftPowerMeterTde?> GetLatestOrDefaultByDateTimeCloseCloseAsync(Guid vesselId,
    //     DateTime startDateTime, DateTime endDateTime)
    // {
    //     try
    //     {
    //         var dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);
    //
    //         await using var command = TDConnection.CreateCommand();
    //
    //         command.CommandText =
    //             $"SELECT ts, speed, torque, power, total_revs, total_eng FROM {dbName}.{SubTableName} WHERE ts >= '{startDateTime.ToFormattedUtcString()}' AND ts <= '{endDateTime.ToFormattedUtcString()}' ORDER BY ts DESC LIMIT 1;";
    //
    //         await using var reader = await command.ExecuteReaderAsync();
    //
    //         if (await reader.ReadAsync())
    //         {
    //             var spm = new ShaftPowerMeterTde
    //             {
    //                 Ts = reader.GetDateTime(0).ToUniversalTime(),
    //                 Speed = reader.GetValue(1),
    //                 Torque = reader.GetValue(2),
    //                 Power = reader.GetValue(3),
    //                 TotalRevs = reader.GetInt64(4),
    //                 TotalEng = reader.GetInt64(5)
    //             };
    //
    //             return spm;
    //         }
    //
    //         return null;
    //     }
    //     catch (Exception ex)
    //     {
    //         _logger.LogError(ex,
    //             $"TDengine 仓储: {nameof(DigitalTDRepository)}.{nameof(GetLatestOrDefaultByDateTimeCloseCloseAsync)} 失败");
    //         throw new TDengineRepositoryException(vesselId, null, startDateTime, endDateTime,
    //             "询 shaft_power_meter 指定时间范围内的最新一条数据，前闭后闭区间 失败", ex);
    //     }
    // }

    /// <summary>
    /// 查询 shaft_power_meter 指定 endDateTime 时间前（含）的最新一条数据
    /// </summary>
    /// <param name="vesselId"></param>
    /// <param name="endDateTime"></param>
    /// <returns></returns>
    public async Task<ShaftPowerMeterTde?> GetLatestOrDefaultByDateTimeAsync(Guid vesselId, DateTime endDateTime)
    {
        try
        {
            var dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);

            await using var command = TDConnection.CreateCommand();

            command.CommandText =
                $"SELECT ts, speed, torque, power, total_revs, total_eng FROM {dbName}.{SubTableName} WHERE ts <= '{endDateTime.ToFormattedUtcString()}' ORDER BY ts DESC LIMIT 1;";

            await using var reader = await command.ExecuteReaderAsync();

            if (await reader.ReadAsync())
            {
                var spm = new ShaftPowerMeterTde
                {
                    Ts = reader.GetDateTime(0).ToUniversalTime(),
                    Speed = reader.GetValue(1) as float? ?? default,
                    Torque = reader.GetValue(2) as float? ?? default,
                    Power = reader.GetValue(3) as float? ?? default,
                    TotalRevs = reader.GetInt64(4),
                    TotalEng = reader.GetInt64(5)
                };

                return spm;
            }

            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex,
                $"TDengine 仓储: {nameof(DigitalTDRepository)}.{nameof(GetLatestOrDefaultByDateTimeAsync)} 失败");
            throw new TDengineRepositoryException(vesselId, null, null, endDateTime,
                "查询 shaft_power_meter 指定 endDateTime 时间前（含）的最新一条数据 失败", ex);
        }
    }

    /// <summary>
    /// 查询 shaft_power_meter 指定时间范围内的数据，前闭后开区间
    /// </summary>
    /// <param name="vesselId"></param>
    /// <param name="startDateTime"></param>
    /// <param name="endDateTime"></param>
    /// <param name="skipCount"></param>
    /// <param name="maxResultCount"></param>
    /// <returns></returns>
    public async Task<(int totalCount, List<ShaftPowerMeterTde> shaftPowerMeterTdes)> GetListByDateTimeAsync(Guid vesselId, DateTime startDateTime,
        DateTime endDateTime, int skipCount, int maxResultCount)
    {
        try
        {
            var dbName = PhmeeConst.GetDbName(DbPrefix, vesselId);

            List<ShaftPowerMeterTde> shaftPowerMeters = [];

            string whereClause = $"ts >= '{startDateTime.ToFormattedUtcString()}' AND ts < '{endDateTime.ToFormattedUtcString()}'";

            await using var command = TDConnection.CreateCommand();
            
            // Query total count
            command.CommandText = $"SELECT COUNT(*) FROM {dbName}.{SubTableName} WHERE {whereClause};";
            var totalCount = Convert.ToInt32(await command.ExecuteScalarAsync());

            // Query actual data
            command.CommandText =
                $"SELECT ts, speed, torque, power, total_revs, total_eng FROM {dbName}.{SubTableName} WHERE {whereClause} ORDER BY ts DESC LIMIT {maxResultCount} OFFSET {skipCount};";

            await using var reader = await command.ExecuteReaderAsync();

            while (await reader.ReadAsync())
            {
                shaftPowerMeters.Add(new ShaftPowerMeterTde
                {
                    Ts = reader.GetDateTime(0).ToUniversalTime(),
                    Speed = reader.GetValue(1) as float? ?? default,
                    Torque = reader.GetValue(2) as float? ?? default,
                    Power = reader.GetValue(3) as float? ?? default,
                    TotalRevs = reader.GetInt64(4),
                    TotalEng = reader.GetInt64(5)
                });
            }

            return (totalCount, shaftPowerMeters);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"TDengine 仓储: {nameof(DigitalTDRepository)}.{nameof(GetListByDateTimeAsync)} 失败");
            throw new TDengineRepositoryException(vesselId, null, startDateTime, endDateTime,
                "查询 shaft_power_meter 指定时间范围内的数据，前闭后开区间 失败", ex);
        }
    }
}